home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 008 / tdraw300.arc / UNCRUNCH.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1987-10-20  |  8.5 KB  |  163 lines

  1. procedure UNCRUNCH (var Addr1,Addr2; BlkLen:Integer);
  2.  
  3. {This is the flash display routine used to display crunched TheDraw image
  4.  files.  It uses a custom protocol for reproducing a image with any
  5.  possible color combinations.  The control codes below #32 are reserved
  6.  for this function.  The following data structure shows the format of a
  7.  sequence.  Not all operations use the optional bytes <x> or <y>..
  8.  
  9.  Data Structure:  <current byte>[<x>[<y>]]
  10.  
  11.     0..15 = New Foreground Color
  12.    16..23 = New Background Color
  13.        24 = Go down to next line, return to same horizontal position as when
  14.             routine was started (akin to a c/r).
  15.        25 = Displays <x> number of spaces.
  16.        26 = Displays <x> number of <y>.  Also used to display ANY characters
  17.             below #32.  This function is the only way to do this although it
  18.             uses three bytes.  Otherwise the character would be interpreted
  19.             as another command code.
  20.        27 = Toggles on/off the foreground attribute blink flag.
  21.  
  22.  
  23.  ----------------------------------------------------------------------------
  24.  
  25.  To use this routine you call the procedure with the ImageData as the
  26.  first parameter, the display address as the second parameter, and the
  27.  length of the ImageData as the third parameter.
  28.  
  29.  Assume we have a ImageData file of a 40 character by 10 line block.  Also
  30.  the following defintions.  ie:
  31.  
  32.    type ScreenType = array [0..3999] of Byte;
  33.    var  ScreenAddr : ScreenType absolute $B800:$0000;
  34.  
  35.    const ImageData : array [1..467] of Byte =
  36.      (...list of image bytes here...);
  37.  
  38.    begin
  39.      UnCrunch (ImageData,ScreenAddr[ (34*2) + (5*160) -162],467);
  40.    end;
  41.  
  42.  
  43.  SCREENADDR is a variable mapped to the same location as the physical video
  44.  addresses (using Turbo's absolute addressing).   The fairly complex array
  45.  address in the call tells UnCrunch where to start displaying the ImageData
  46.  40 character by 10 line block.  The 34*2 indicates the horizontal position
  47.  number 34 with the 5*160 indicating line number 5.  This is similar to a
  48.  Turbo GOTOXY (34,5) statement, except it works for UnCrunch instead.
  49.  
  50.  The value of 467 used in the call is the length of the array as indicated
  51.  in the CONST statement.
  52.  
  53.  UnCrunch remembers the horizontal (X) starting position when it goes down
  54.  to the next line.  This allows you to display the ImageData block correctly
  55.  at any position on the screen.   ie:
  56.  
  57.    +-------------------------------------------------+
  58.    |                                                 |
  59.    |                                                 | <- Pretend this
  60.    |                                                 |    is the video
  61.    |           ┌─────────────────────┐               |    display.
  62.    |           │█████████████████████│               |
  63.    |           │█████████████████████│               |
  64.    |           │██ ImageData block ██│               |
  65.    |           │█████████████████████│               |
  66.    |           │█████████████████████│               |
  67.    |           │█████████████████████│               |
  68.    |           └─────────────────────┘               |
  69.    |                                                 |
  70.    |                                                 |
  71.    |                                                 |
  72.    +-------------------------------------------------+
  73.  
  74.  
  75.  The ImageData block could just as well have been display in the upper-left
  76.  corner of the screen with:
  77.      UNCRUNCH (ImageData,ScreenAddr[ (1*2) + (1*160) -162],467);
  78.  
  79.  Notice the array address changed to the equivilant of GOTOXY (1,1);
  80.  
  81.  To display the block in the lower-right corner you would use:
  82.      UNCRUNCH (ImageData,ScreenAddr[ (40*2) + (15*160) -162],467);
  83.  
  84.  The block is 40 characters wide by 10 lines deep.  Therefore to display
  85.  such a large block, we must display the block at GOTOXY (40,15);
  86.  
  87.  
  88.  Obviously I have been attempting to describe this procedure by use of
  89.  examples.  This was done because I felt it to be the easiest and clearest
  90.  way explaining the procedure.  It was designed to be as simple as possible,
  91.  however for some people the best way to learn it is to experiment.  Try
  92.  creating a program using the above example information.  Use TheDraw to
  93.  make a 40 by 10 block (or any size) to experiment with.  Good luck.  If
  94.  you can devise a better way of explaining this, please share your labors
  95.  with me.   Others will surely benifit.   Thanks!
  96.  
  97. }
  98. begin
  99.   inline (
  100.     $1E/               {       PUSH    DS}
  101.     $C5/$B6/Addr1/     {       LDS     SI,[BP+Addr1]  ;Source Address}
  102.     $C4/$BE/Addr2/     {       LES     DI,[BP+Addr2]  ;Destination Addr}
  103.     $8B/$8E/BlkLen/    {       MOV     CX,[BP+BlkLen] ;Length of block}
  104.     $8B/$D7/           {       MOV     DX,DI          ;Save X coordinate for later.}
  105.     $33/$C0/           {       XOR     AX,AX          ;Set Current attributes.}
  106.     $AC/               {LOOPA: LODSB                  ;Get next character.}
  107.     $3C/$1B/           {       CMP     AL,27          ;Does user want to toggle the blink}
  108.     $75/$05/           {       JNZ     ForeGround     ;attibute?}
  109.     $80/$F4/$80/       {       XOR     AH,128         ;Done.}
  110.     $EB/$4D/           {       JMP     Short Next}
  111.                        {ForeGround:}
  112.     $3C/$10/           {       CMP     AL,16          ;If less than 16, then change the}
  113.     $73/$07/           {       JNC     BackGround     ;foreground color.  Otherwise jump.}
  114.     $80/$E4/$70/       {       AND     AH,70H         ;Strip off old foreground.}
  115.     $0A/$E0/           {       OR      AH,AL}
  116.     $EB/$42/           {       JMP     Short Next}
  117.                        {BackGround:}
  118.     $3C/$18/           {       CMP     AL,24          ;If less than 24, then change the}
  119.     $74/$13/           {       JZ      NextLine       ;background color.  If exactly 24,}
  120.     $73/$19/           {       JNC     MultiOutput    ;then jump down to next line.}
  121.     $2C/$10/           {       SUB     AL,16          ;Otherwise jump to multiple output}
  122.     $02/$C0/           {       ADD     AL,AL          ;routines.}
  123.     $02/$C0/           {       ADD     AL,AL}
  124.     $02/$C0/           {       ADD     AL,AL}
  125.     $02/$C0/           {       ADD     AL,AL}
  126.     $80/$E4/$8F/       {       AND     AH,8FH         ;Strip off old background.}
  127.     $0A/$E0/           {       OR      AH,AL}
  128.     $EB/$2B/           {       JMP     Short Next}
  129.                        {NextLine:}
  130.     $81/$C2/$A0/$00/   {       ADD     DX,160         ;If equal to 24,}
  131.     $8B/$FA/           {       MOV     DI,DX          ;then jump down to}
  132.     $EB/$23/           {       JMP     Short Next     ;the next line.}
  133.                        {MultiOutput:}
  134.     $3C/$19/           {       CMP     AL,25          ;If equal to 25,}
  135.     $75/$0B/           {       JNZ     NotMultiSpaces ;then using the}
  136.     $AC/               {       LODSB                  ;following code as}
  137.     $51/               {       PUSH    CX             ;a count, output}
  138.     $32/$ED/           {       XOR     CH,CH          ;said number of}
  139.     $8A/$C8/           {       MOV     CL,AL          ;spaces.}
  140.     $B0/$20/           {       MOV     AL,32}
  141.     $EB/$0D/$90/       {       JMP     StartOutput    ;Use below loop.}
  142.                        {NotMultiSpaces:}
  143.     $3C/$1A/           {       CMP     AL,26          ;If equal to 26, then using}
  144.     $75/$0F/           {       JNZ     NormalLetter   ;the following two codes, display}
  145.     $AC/               {       LODSB                  ;<x> number of <y> characters.}
  146.     $49/               {       DEC     CX             ;Adjust main counter.}
  147.     $51/               {       PUSH    CX             ;Display as many of}
  148.     $32/$ED/           {       XOR     CH,CH          ;whatever the user}
  149.     $8A/$C8/           {       MOV     CL,AL          ;wants.}
  150.     $AC/               {       LODSB                  ;Get character.}
  151.                        {StartOutput:}
  152.     $E3/$03/           {       JCXZ    Stop           ;Abort if already at zilch.}
  153.     $AB/               {LOOPB: STOSW}
  154.     $E2/$FD/           {       LOOP    LOOPB}
  155.     $59/               {Stop:  POP     CX}
  156.     $49/               {       DEC     CX             ;Adjust main counter.}
  157.                        {NormalLetter:}
  158.     $AB/               {       STOSW                  ;Save screen letter.}
  159.     $E3/$02/           {Next:  JCXZ    Done           ;Get next, unless CX}
  160.     $E2/$A5/           {       LOOP    LOOPA          ;has already one to zero.}
  161.     $1F);              {Done:  POP     DS}
  162. end; {UNCRUNCH}
  163.